package chatclient.applets.canvas;

import chatclient.applets.note.Note;
import chatclient.tools.NoteContainer;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentEvent;
import java.util.Vector;

public class NoteCanvas extends ChatCanvas
        implements AdjustmentListener {

    private final Object sync;
    private int fixIndex;
    private boolean fixTop;
    private Vector notes;
    private int height;
    private int top;
    private int bottom;

    public NoteCanvas(NoteContainer notecontainer, String s, boolean flag) {
        super(notecontainer, s);
        this.sync = new Object();
        this.notes = new Vector();
        this.height = 0;
        this.top = 0;
        this.bottom = 0;
        this.fixIndex = (flag ? -1 : 0);
        this.fixTop = flag;
        checkBoundaries();
    }

    public int getTop() {
        return this.top < 0 ? 0 : this.top;
    }

    public void setTop(int i) {
        if (i == this.top) {
            return;
        }

        this.bottom += i - this.top;
        this.top = i;
        checkBoundaries();
        repaint();
    }

    public int getBottom() {
        return this.bottom > this.height ? this.height : this.bottom;
    }
 
    public void setBottom(int i) {
        if (i == this.bottom) {
            return;
        }

        this.top += i - this.bottom;
        this.bottom = i;
        checkBoundaries();
        repaint();
    }

    private void checkTop() {
        if (this.top < 0) {
            this.top = 0;
        }
        this.bottom = (this.top + size().height);
    }

    private void checkBottom() {
        if (this.bottom > this.height) {
            this.bottom = this.height;
        }
        this.top = (this.bottom - size().height);
    }

    private void checkBoundaries() {
        if (this.fixTop) {
            checkBottom();
            checkTop();
        } else {
            checkTop();
            checkBottom();
        }
    }

    public int getMinimum() {
        return 0;
    }

    public int getMaximum() {
        return this.height;
    }

    public int getVisible() {
        return size().height;
    }

    public int getAverageNoteHeight() {
        int i = this.notes.size();
        return i != 0 ? this.height / i : 0;
    }

    public int getNoteCount() {
        return this.notes.size();
    }

    public void addNote(Note note) {
        addNote(note, -1);
    }

    public void addNote(Note note, int i) {
        note.setWidth(size().width);
        int j = note.getHeight();
        synchronized (this.sync) {
            if (i == -1) {
                i = this.notes.size();
            }
            this.notes.insertElementAt(note, i);
            this.height += j;
            if (i <= this.fixIndex) {
                this.fixIndex += 1;
                this.top += j;
                this.bottom += j;
            }
            checkBoundaries();
        }
        repaint();
    }

    public void replaceNote(Note note, int i) {
        note.setWidth(size().width);
        int j = note.getHeight();
        synchronized (this.sync) {
            this.height -= ((Note) this.notes.elementAt(i)).getHeight();
            this.height += j;
            this.notes.setElementAt(note, i);
            checkBoundaries();
        }
        repaint();
    }

    public void removeNote(int i) {
        synchronized (this.sync) {
            Note note = (Note) this.notes.elementAt(i);
            int j = note.getHeight();
            this.notes.removeElementAt(i);
            this.height -= j;
            if (i <= this.fixIndex) {
                this.fixIndex -= 1;
                this.top -= j;
                this.bottom -= j;
            }
            checkBoundaries();
        }
        repaint();
    }

    public void removeAllNotes() {
        synchronized (this.sync) {
            this.notes = new Vector();
            this.height = 0;
            this.top = 0;
            this.bottom = 0;
            this.fixIndex = (this.fixTop ? -1 : 0);
            checkBoundaries();
        }
        repaint();
    }

    public int findNoteAtPosition(int i, int j) {
        synchronized (this.sync) {
            int k = -this.top;
            int l = 0;
            do {
                Note note = (Note) this.notes.elementAt(l);
                int i1 = note.getHeight();
                int j1 = k + i1;
                if ((k <= j) && (j1 > j)) {
                    int k1 = l;
                    return k1;
                }
                k = j1;

                l++;
                if (l >= this.notes.size()) {
                    break;
                }
            } while (k < this.bottom);
        }

        return -1;
    }

    public void fixNote(int i) {
        this.fixIndex = i;
    }

    public void unfixNote() {
        this.fixIndex = (this.fixTop ? -1 : 0);
    }

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);
                
        if (!isVisible()) {
            return;
        }

        synchronized (this.sync) {
            if (this.fixTop) {
                int i = 0;
                int k = 0;
                do {
                    
                    try {
                    Note note = (Note) this.notes.elementAt(k);
                    int i1 = note.getHeight();
                    int k1 = i + i1;
                    if (k1 > this.top) {
                        Color color = note.getBackgroundForBgImage(getStyle());
                        if (color != null) {
                            g.setColor(color);
                            g.fillRect(0, i - this.top, size().width, i1);
                        }
                        note.paint(g, 0, i - this.top, getStyle(), false);
                    }
                    i = k1;

                    k++;
                    if (k >= this.notes.size()) {
                        break;
                    }
                    } catch(Exception e)
                    {
                        break;
                    }
                } while (i < this.bottom);
            } else {
                int j = this.height;
                int l = this.notes.size() - 1;
                do {
                    try {
                    Note note1 = (Note) this.notes.elementAt(l);
                    int j1 = note1.getHeight();
                    int l1 = j - j1;
                    if (l1 < this.bottom) {
                        Color color1 = note1.getBackgroundForBgImage(getStyle());
                        if (color1 != null) {
                            g.setColor(color1);
                            g.fillRect(0, l1 - this.top, size().width, j1);
                        }
                        note1.paint(g, 0, l1 - this.top, getStyle(), false);
                    }
                    j = l1;

                    l--;
                    if (l < 0) {
                        break;
                    }
                    } catch(Exception e) { break; }
                } while (j > this.top);
            }
        }
    }

    @Override
    public void layout() {
        super.layout();
        synchronized (this.sync) {
            for (int i = 0; i < this.notes.size(); i++) {
                Note note = (Note) this.notes.elementAt(i);
                int j = note.getHeight();
                note.setWidth(size().width);
                this.height += note.getHeight() - j;
                if (i > this.fixIndex) {
                    continue;
                }
                this.top += note.getHeight() - j;
                this.bottom += note.getHeight() - j;
            }

            checkBoundaries();
        }
    }

    @Override
    public void adjustmentValueChanged(AdjustmentEvent adjustmentevent) {
        setTop(adjustmentevent.getValue());
        repaint();
    }

    @Override
    public void componentResized(ComponentEvent componentevent) {
        layout();
        super.componentResized(componentevent);
    }

    @Override
    public void noteHeightChanged(Note note) {
        if (!isVisible()) {
            return;
        }

        layout();
        super.noteHeightChanged(note);
    }
}
